package com.amumu.drama.common.modules.delivery.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.amumu.drama.common.constant.*;
import com.amumu.drama.common.exception.Asserts;
import com.amumu.drama.common.modules.delivery.config.DeliveryConfig;
import com.amumu.drama.common.modules.delivery.dto.DeliveryOrderStatusQueryResp;
import com.amumu.drama.common.modules.delivery.dto.DeliveryStatusResp;
import com.amumu.drama.common.modules.delivery.dto.req.DeliveryHandleDTO;
import com.amumu.drama.common.modules.delivery.handler.DeliveryHandler;
import com.amumu.drama.common.modules.delivery.service.DeliveryService;
import com.amumu.drama.common.modules.order.dto.OmsOrderDetail;
import com.amumu.drama.common.modules.order.dto.req.AdminDeliverySuccessReq;
import com.amumu.drama.common.modules.order.manager.OrderManager;
import com.amumu.drama.common.modules.order.mapping.DeliveryOrderStatusQueryRespFromOmsOrderMapping;
import com.amumu.drama.common.modules.order.mapping.DeliveryOrderStatusQueryRespMapping;
import com.amumu.drama.common.modules.order.service.OmsPortalOrderService;
import com.amumu.drama.mapper.OmsOrderOperateHistoryMapper;
import com.amumu.drama.mapper.OrderMapper;
import com.amumu.drama.mapper.PmsSkuStockMapper;
import com.amumu.drama.mapper.recharge.ThirdRechargeLogMapper;
import com.amumu.drama.model.OmsOrder;
import com.amumu.drama.model.OmsOrderItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author sunzhuang
 * @date 2024/6/27 09:03
 * @slogan 天下风云出我辈, 一入代码岁月催
 * @desc 福禄发货代码
 */

@Slf4j
@Service
public class DeliveryServiceImpl implements DeliveryService {


    @Autowired
    private OmsPortalOrderService omsPortalOrderService;

    @Autowired
    private PmsSkuStockMapper skuStockMapper;

    @Autowired
    private OrderManager orderManager;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ThirdRechargeLogMapper thirdRechargeLogMapper;

    @Autowired
    private OmsOrderOperateHistoryMapper orderOperateHistoryMapper;

    /***
     * （通用）处理发货
     * @param orderId
     */
    @Override
    public void delivery(Long orderId, DeliveryHandleDTO deliveryHandleDTO, OperateTypeEnum operateTypeEnum, Long operateId) {
        //查询订单sku
        OmsOrderDetail orderDetail = omsPortalOrderService.detail(orderId);
        if (orderDetail == null) {
            log.error("订单详情为空：orderId={}", orderId);
            Asserts.fail("订单详情为空");
        }
        PayStatusEnum payStatusEnum = PayStatusEnum.getByCode(orderDetail.getPayStatus());
        if (!OrderStatusEnum.WAIT_DELIVERY.getCode().equals(orderDetail.getStatus()) ||
                !PayStatusEnum.SUCCESS.getCode().equals(orderDetail.getPayStatus()) ||
                !DeliveryStatusEnum.WAIT_DELIVERY.getCode().equals(orderDetail.getDeliveryStatus())) {
            log.error("订单状态异常，无法发货！orderId:{},orderStatus:{},payStatus:{},deliveryStatus:{}", orderDetail.getId(), orderDetail.getStatus(), orderDetail.getPayStatus(), orderDetail.getDeliveryStatus());
            Asserts.fail(StrUtil.format("订单状态[{}],发货状态：[{}]，无法发货！",
                    OrderStatusEnum.getByCode(orderDetail.getStatus()).getDesc(),
                    DeliveryStatusEnum.getByCode(orderDetail.getDeliveryStatus()).getDesc()));
        }
        List<OmsOrderItem> orderItemList = orderDetail.getOrderItemList();
        if (CollUtil.isEmpty(orderItemList)) {
            log.error("订单详情为空：orderId={}", orderId);
            Asserts.fail("订单详情的订单项为空");
        }
        //根据订单的供货商选择发货处理器
        DeliveryHandler deliveryHandler = DeliveryConfig.getDeliveryHandler(orderDetail.getOrderType(), orderDetail.getDeliveryProvider());
        if (deliveryHandler == null) {
            log.error("订单的发货处理器为空，orderId:{},orderType:{},deliveryProvider:{}", orderId, orderDetail.getOrderType(), orderDetail.getDeliveryProvider());
            Asserts.fail("查找发货处理器失败，请稍后重试");
        }
        try {
            DeliveryStatusResp deliveryResp = deliveryHandler.delivery(orderId, orderDetail, deliveryHandleDTO);
            orderManager.updateOrderDeliveryStatus(orderId, orderDetail, deliveryResp, operateTypeEnum, operateId);
        } catch (Exception e) {
            log.error("发货失败：发货处理器：{}", deliveryHandler.getClass().getSimpleName(), e);
        }
    }


    /**
     * 发货回调
     */
    @Override
    public Object deliveryNotify(String deliveryType, Map<String, String> params, String body) {
        DeliveryHandler deliveryHandler = DeliveryConfig.getDeliveryHandlerByType(deliveryType);
        if (deliveryHandler == null) {
            log.error("未找到对应的发货处理器，deliveryType:{}", deliveryType);
            return FuluRespCode.ORDER_STATUS_FAIL;
        }
        try {
            DeliveryStatusResp deliveryResp = deliveryHandler.deliveryNotify(params, body);
            orderManager.updateOrderDeliveryStatus(null, null, deliveryResp, OperateTypeEnum.DELIVERY_NOTIFY, null);
            return deliveryResp.getNotifyRespInfo();
        } catch (Exception e) {
            //订单直充失败
            log.error("福禄直充回调失败:deliveryType:{},params:{},body:{}", deliveryType, params, body, e);
            return FuluRespCode.ORDER_STATUS_FAIL;
        }
    }

    /***
     * （接口直充）轮询查询订单状态
     * @param orderId
     */
    @Override
    public DeliveryOrderStatusQueryResp pollQueryDeliveryStatus(Long orderId, OmsOrder omsOrder, OperateTypeEnum operateTypeEnum, Long operateId,boolean deliveryStatusExist) {
        //查询订单sku
        omsOrder = orderManager.getOmsOrderHighly(omsOrder, orderId, null, null);
        if (omsOrder == null) {
            log.error("订单详情为空：orderId={}", orderId);
            Asserts.fail("订单详情为空");
        }
        DeliveryOrderStatusQueryResp resp = DeliveryOrderStatusQueryRespFromOmsOrderMapping.INSTANCE.convertTo(omsOrder);
        if (!OrderStatusEnum.WAIT_DELIVERY.equals(resp.getOrderStatusEnum()) ||
                !PayStatusEnum.SUCCESS.equals(resp.getPayStatusEnum()) ||
                !DeliveryStatusEnum.DELIVERY.equals(resp.getDeliveryStatusEnum())) {
            log.error("订单状态异常，无法查询发货状态！orderId[{}],orderStatus[{}],payStatus[{}],deliveryStatus[{}]", omsOrder
                            .getId(), resp.getOrderStatusEnum().getDesc(),
                    resp.getPayStatusEnum().getDesc(),
                    resp.getDeliveryStatusEnum().getDesc());
            resp.setMsg("订单状态不在发货中，无需轮询查询");
            return resp;
        }
        //根据订单的供货商选择发货处理器
        DeliveryHandler deliveryHandler = DeliveryConfig.getDeliveryHandler(omsOrder.getOrderType(), omsOrder.getDeliveryProvider());
        if (deliveryHandler == null) {
            log.error("订单的发货处理器为空，orderId:{},orderType:{},deliveryProvieder:{}", orderId, omsOrder.getOrderType(), omsOrder.getDeliveryProvider());
            Asserts.fail("查找发货处理器失败，请稍后重试");
        }
        DeliveryStatusResp deliveryStatusResp = deliveryHandler.pollQueryDeliveryStatus(orderId, omsOrder);
        orderManager.updateOrderDeliveryStatus(orderId, omsOrder, deliveryStatusResp, operateTypeEnum, operateId);
        // 返回订单最新的状态
        OmsOrderDetail orderDetailNew = omsPortalOrderService.detail(orderId);
        DeliveryOrderStatusQueryResp deliveryResp = DeliveryOrderStatusQueryRespMapping.INSTANCE.convertTo(orderDetailNew);
        if (deliveryStatusExist){
            deliveryResp.setDeliveryStatusResp(deliveryStatusResp);
        }
        return deliveryResp;
    }

    /***
     * （人工）发货成功
     * @param request
     */
    @Override
    public void deliverySuccess(AdminDeliverySuccessReq request, OperateTypeEnum operateTypeEnum, Long operatorId) {
        OmsOrder omsOrder = orderMapper.selectById(request.getOrderId());
        if (Objects.equals(DeliveryStatusEnum.WAIT_DELIVERY.getCode(), omsOrder.getDeliveryStatus())) {
            Asserts.fail(StrUtil.isBlank(request.getDeliverySn()), "必须填写发货号");
        }

        DeliveryStatusResp deliveryStatusResp = new DeliveryStatusResp();
        deliveryStatusResp.setDeliveryStatusEnum(DeliveryStatusEnum.SUCCESS);
        deliveryStatusResp.setDeliverySn(request.getDeliverySn());
        deliveryStatusResp.setMsg("人工发货成功");
        orderManager.updateOrderDeliveryStatus(request.getOrderId(), null, deliveryStatusResp, OperateTypeEnum.ADMIN, operatorId);
    }

    /***
     * （人工）发货失败
     * @param orderId
     */
    @Override
    public void deliveryFail(Long orderId, OperateTypeEnum operateTypeEnum, Long operatorId) {

    }

    /**
     * （暂时不用）退货
     *
     * @param orderId
     */
    @Override
    public void refund(Long orderId) {

    }


}
